﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.Objects;
using System.Data.Metadata.Edm;
using System.Data.Objects.DataClasses;
using ControlePonto.Extensions;
using ControlePonto.Models;
using System.Linq.Expressions;

namespace ControlePonto.Controllers
{
    public class CRUDBaseController<TEntity, TObjectContext> : Controller
        where TEntity : EntityObject
        where TObjectContext : ObjectContext
    {
        TObjectContext context;
        RepositoryBase<TEntity, int> repo;
        public CRUDBaseController(TObjectContext context)
        {
            this.context = context;
            this.repo = new RepositoryBase<TEntity, int>(context);
        }
        public CRUDBaseController() : this( ContextManager.GetContext<TObjectContext>())
        {   
        }


        public static int GetMaxValue<T>(ObjectContext context, string keyFieldName)
        {
            if (null != context)
            {
                try
                {
                    // Now I can get desire entityset from context using reflection.
                    System.Data.Objects.ObjectQuery<T> query = context.GetType().GetProperties().Where(
                                                                            p => p.PropertyType.BaseType.Equals(typeof(System.Data.Objects.ObjectQuery)) && 
                                                                            p.PropertyType.GetGenericArguments().First().Equals(typeof(T))
                    
                                                                            ).First().GetValue(context, null) as System.Data.Objects.ObjectQuery<T>;

                    // First we define the parameter that we are going to use the clause.
                    var param = Expression.Parameter(typeof(T), typeof(T).Name);
                    // Now we’ll make our lambda function that returns the "ID" property .
                    var maxExpression = Expression.Lambda<Func<T, int>>(Expression.Property(param, keyFieldName), param);
                    
                    if (null != query)
                    {
                        int? i = query.Max<T, int>(maxExpression);
                        if (i.HasValue)
                            return i.Value;
                    }
                }
                catch (Exception) { }
            }
            return 0;
        }
        //
        // GET: /CRUDBase/

        public ActionResult Index()
        {
            
    
            return View(repo.ListAll());
        }

        //
        // GET: /CRUDBase/Details/5

        public ActionResult Details(int id)
        {
            return View();
        }

        //
        // GET: /CRUDBase/Create

        public ActionResult Create()
        {

            return View();
        }
        //
        // POST: /CRUDBase/Create

        [HttpPost]
        public ActionResult Create(TEntity collection)
        {
            try
            {
                // TODO: Add insert logic here
                if ( ModelState.IsValid )
                {
                    repo.Insert(collection);
                    
                }
                return RedirectToAction("Index");
                
            }
            catch
            {
                return View();
            }
        }

        //
        // GET: /CRUDBase/Edit/5

        public ActionResult Edit(int id)
        {
            return View();
        }

        //
        // POST: /CRUDBase/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
            try
            {
                // TODO: Add update logic here

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        //
        // GET: /CRUDBase/Delete/5

        public ActionResult Delete(int id)
        {
            return View();
        }

        //
        // POST: /CRUDBase/Delete/5

        [HttpPost]
        public ActionResult Delete(int id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
    }
}
